Unlike K-means algorithm, each data object is not the member of only one cluster but is the member of all clusters with varying degrees of memberhip between 0 and 1.

In our case , each data object belong to ONLY one cellular component nuclear, cytoplasm or membrane.

Conclusion: 1 - fcm and pfcm takes a lot of time if we use high image resolution 2 - k-means method seems to be more suitable.

im <- readImage("basales.jpg")
dim(im)
## [1] 1024  768    3
plot(im) # raster method means within R

##  I. reduce the size of image 
# scale to a specific width and height
   #ims <- resize(im, w = 200, h = 100)

# II. scale by 50%; the height is determined automatically so that
# the aspect ratio is preserved
ims <- resize(im, dim(im)[1]/8)
ims
## Image 
##   colorMode    : Color 
##   storage.mode : double 
##   dim          : 128 96 3 
##   frames.total : 3 
##   frames.render: 1 
## 
## imageData(object)[1:5,1:6,1]
##           [,1]      [,2]      [,3]      [,4]      [,5]      [,6]
## [1,] 0.8235294 0.8225490 0.8127451 0.7823529 0.7833333 0.7980392
## [2,] 0.8137255 0.7970588 0.7843137 0.7656863 0.7156863 0.7882353
## [3,] 0.8196078 0.7460784 0.7833333 0.7725490 0.8196078 0.8343137
## [4,] 0.7872549 0.8362745 0.8764706 0.8313725 0.8843137 0.8382353
## [5,] 0.7921569 0.8725490 0.8980392 0.8500000 0.8784314 0.8774510
plot(ims)

# reshape image into a data frame
df = data.frame(
  red = matrix(ims[,,1], ncol=1),
  green = matrix(ims[,,2], ncol=1),
  blue = matrix(ims[,,3], ncol=1)
)
str(df)
## 'data.frame':    12288 obs. of  3 variables:
##  $ red  : num  0.824 0.814 0.82 0.787 0.792 ...
##  $ green: num  0.801 0.785 0.768 0.725 0.696 ...
##  $ blue : num  0.788 0.799 0.775 0.773 0.759 ...

Unsupervised Possibilistic Fuzzy C-Means algorithm

# Possibilistic Fuzzy C-Means Clustering Algorithm
## this run takes a lot of time even I reduce the size of image by 4
# res.pfcm <- ppclust::pfcm(df, centers=5)
# a numeric matrix containing the final cluster prototypes.
# res.pfcm$v
#                 red     green      blue
# Cluster 1 0.8420613 0.6191732 0.6977437
# Cluster 2 0.8182934 0.4876898 0.5617337
# Cluster 3 0.8720549 0.7644502 0.7797300
# Cluster 4 0.8355903 0.5195514 0.6029807
# Cluster 5 0.6927238 0.4240574 0.5330456
# a numeric matrix containing the typicality degrees of the data objects.
# head(res.pfcm$t)
#   Cluster 1  Cluster 2 Cluster 3  Cluster 4  Cluster 5
# 1 0.1288446 0.02401000 0.5443269 0.04291962 0.02055977
# 2 0.1372704 0.02475138 0.5163443 0.04446920 0.02134524
# 3 0.1778028 0.02888067 0.6170897 0.05291714 0.02388038
# 4 0.2379715 0.03496650 0.3370548 0.06518729 0.02919441
# 5 0.3363520 0.04244848 0.2810300 0.08164521 0.03373603
# 6 0.2753612 0.04541603 0.1528285 0.08426691 0.03965113
# a numeric matrix containing the distances of objects to the final cluster proto- types
# head(res.pfcm$d)
#  Cluster 1  Cluster 2   Cluster 3  Cluster 4 Cluster 5
# 1 0.04158602 0.14948141 0.003761511 0.11366701 0.2243028
# 2 0.03865589 0.14489382 0.004208872 0.10952852 0.2158755
# 3 0.02844168 0.12365149 0.002788159 0.09122913 0.1924584
# 4 0.01969538 0.10149022 0.008837837 0.07309768 0.1565697
# 5 0.01213561 0.08295336 0.011495473 0.05733525 0.1348580
# 6 0.01618590 0.07729278 0.024907817 0.05539285 0.1140377
# a numeric vector containing the cluster labels found by defuzzifying the typicality degrees of the objects.
# res.pfcm$cluster[1:20]
# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 3  3  3  3  1  1  1  1  3  1  1  4  4  4  4  4  2  2  5  5 
#unique(res.pfcm$cluster)
#[1] 3 1 4 2 5
# a numeric vector for the number of objects in the clusters.
# res.pfcm$csize
#   1    2    3    4    5 
# 2892 2028 2610 2174 2584
# df$label = res.pfcm$cluster
  
  ### Replace the color of each pixel in the image with the mean 
  ### R,G, and B values of the cluster in which the pixel resides:
  
  # # get the coloring
  # colors = data.frame(
  #   label = 1:nrow(res.pfcm$centers), 
  #   R = res.pfcm$v[,"red"],
  #   G = res.pfcm$v[,"green"],
  #   B = res.pfcm$v[,"blue"]
  # )
  # 
  # # merge color codes on to df
  # # IMPORTANT: we must maintain the original order of the df after the merge!
  # 
  # df$order <- 1:nrow(df)
  # df <- merge(df, colors)
  # 
  # 
  # # reorder the matrix (image)
  #   df <- df[order(df$order),]
  #   df$order = NULL
  #   
  #   # get mean color channel values for each row of the df.
  #   R <- matrix(df$R, nrow=dim(ims)[1])
  #   G <- matrix(df$G, nrow=dim(ims)[1])
  #   B <- matrix(df$B, nrow=dim(ims)[1])
  #   
  #   # reconstitute the segmented image in the same shape as the input image
  #   im.segmented <- array(dim=dim(ims))
  #   im.segmented[,,1] = R
  #   im.segmented[,,2] = G
  #   im.segmented[,,3] = B
  #   
  #   im.segmented <- EBImage::Image(im.segmented, colormode=Color)
  #   
  #   plot(im.segmented)

Partitioning Cluster Analysis Using Fuzzy C-Means

im <- readImage("basales.jpg")
dim(im)
## [1] 1024  768    3
# II. scale by 50%; the height is determined automatically so that
# the aspect ratio is preserved
ims <- resize(im, dim(im)[1]/8)
plot(ims)

# reshape image into a data frame
# df = data.frame(
#   red = matrix(ims[,,1], ncol=1),
#   green = matrix(ims[,,2], ncol=1),
#   blue = matrix(ims[,,3], ncol=1)
# )
# #res.fcm <- ppclust::fcm(df, centers = 5)
# str(res.fcm)
# List of 17
#  $ u         : num [1:12288, 1:5] 0.126 0.173 0.234 0.541 0.726 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
#   .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
#  $ v         : num [1:5, 1:3] 0.837 0.879 0.677 0.818 0.839 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
#   .. ..$ : chr [1:3] "red" "green" "blue"
#  $ v0        : num [1:5, 1:3] 0.719 0.908 0.72 0.839 0.776 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
#   .. ..$ : chr [1:3] "red" "green" "blue"
#  $ d         : num [1:12288, 1:5] 0.02124 0.01897 0.0122 0.00741 0.00357 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
#   .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
#  $ x         : num [1:12288, 1:3] 0.824 0.814 0.82 0.787 0.792 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
#   .. ..$ : chr [1:3] "red" "green" "blue"
#  $ cluster   : Named int [1:12288] 2 2 2 1 1 1 1 1 1 1 ...
#   ..- attr(*, "names")= chr [1:12288] "1" "2" "3" "4" ...
#  $ csize     : Named num [1:5] 2378 2062 2382 3032 2434
#   ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
#  $ sumsqrs   :List of 4
#   ..$ between.ss   : num 372
#   ..$ within.ss    : Named num [1:5] 16.28 8.79 18.12 8.58 11.8
#   .. ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
#   ..$ tot.within.ss: num 63.6
#   ..$ tot.ss       : num 436
#  $ k         : num 5
#  $ m         : num 2
#  $ iter      : num 107
#  $ best.start: int 1
#  $ func.val  : num 34.5
#  $ comp.time : num 177
#  $ inpargs   :List of 8
#   ..$ iter.max: int 1000
#   ..$ con.val : num 1e-09
#   ..$ dmetric : chr "sqeuclidean"
#   ..$ alginitv: chr "kmpp"
#   ..$ alginitu: chr "imembrand"
#   ..$ fixcent : logi FALSE
#   ..$ fixmemb : logi FALSE
#   ..$ stand   : logi FALSE
#  $ algorithm : chr "FCM"
#  $ call      : language ppclust::fcm(x = df, centers = 5)
#  - attr(*, "class")= chr "ppclust"